package org.vaadinpa.gui.views;

import java.util.List;

import org.vaadinpa.Conf;
import org.vaadinpa.data.Ship.ShipType;
import org.vaadinpa.data.TechLevel;
import org.vaadinpa.exceptions.NotEnoughFundsException;
import org.vaadinpa.gui.VaadinPA;
import org.vaadinpa.gui.ViewWithCommands;
import org.vaadinpa.gui.util.NotificationUtil;
import org.vaadinpa.logic.Command;
import org.vaadinpa.logic.CommandHandler;
import org.vaadinpa.logic.commands.TechAdvanceCommand;

import com.vaadin.ui.AbstractOrderedLayout;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import com.vaadin.ui.themes.Reindeer;

public class ResearchView extends ViewWithCommands {

	private static final long serialVersionUID = 2121678886825633380L;
	private final HorizontalLayout grid;

	public ResearchView() {

		grid = new HorizontalLayout();
		grid.setSpacing(true);
		grid.setWidth("100%");

		addComponent(grid);

		reload();
	}

	@Override
	public void reload() {
		super.reload();

		grid.removeAllComponents();
		int currentLevel = VaadinPA.getPlanet().level.ordinal();
		for (TechLevel level : TechLevel.values()) {

			Panel p = new Panel("Level " + (level.ordinal() + 1));
			p.getContent().addStyleName(Reindeer.LAYOUT_BLACK);

			// size trick
			if (level.ordinal() == TechLevel.values().length - 1) {
				p.setHeight(null);
			} else {
				p.setHeight("100%");
				p.getContent().setSizeFull();
			}
			grid.addComponent(p);

			// resource rate
			String descString = "Asteroids bring <b>" + Conf.ROID_RESOURCE_RATE_NEW_LEVEL[level.ordinal()] + "/"
					+ Conf.ROID_RESOURCE_RATE_NORM_LEVEL[level.ordinal()] + "</b> (new/inited)<br>";

			// roid init cost
			descString += "Asteroid init costs <b>" + Conf.ROID_INIT_COST_LEVEL[level.ordinal()]
					+ "</b> of that resource<br>";

			// roid scan success rate
			descString += "Asteroid scan success is <b>";
			int percent = new Double(Conf.ROID_FINDING_RATE_LEVEL[level.ordinal()] * 100).intValue();
			switch (level) {
			case LOWEST:
				descString += "(100-roids) %, min " + percent;
				break;
			case LOW:
				descString += "(80-roids) %, min " + percent + " %";
				break;
			case MODERATE:
			case HIGH:
			case HIGHEST:
				descString += percent + " %";
				break;
			}
			descString += "</b> <br>";

			// ship build level
			descString += "You can build <b>" + ShipType.values()[level.ordinal()] + "</b> level ships<br>";

			// planetary scan results
			descString += "Planetary scans return: <ul>";
			switch (level) {
			case LOWEST:
				descString += "<li>total amount of <b>roids</b>";
				descString += "<li>total number of <b>ships</b>";
				break;
			case LOW:
				descString += "<li><b>amount</b> of each roid type ";
				descString += "<li>total number of ships";
				break;
			case MODERATE:
				descString += "<li>amount of each roid type ";
				descString += "<li>amount of <b>each ship type</b> ";
				descString += "<li>planet <b>tech level</b>";
				break;
			case HIGH:
				descString += "<li>amount of each roid type ";
				descString += "<li>fleet <b>composition and orders</b>";
				descString += "<li>planet tech level";
				break;
			case HIGHEST:
				descString += "<li>amount of each roid type ";
				descString += "<li>fleet composition, orders, <b>target and ETA</b>";
				descString += "<li>planet tech level";
				break;
			}
			descString += "</ul>";

			// knowledge of scans
			switch (level) {
			case LOWEST:
			case LOW:
				break;
			case MODERATE:
				descString += "You know when you have been <b>scanned</b>";
				break;
			case HIGH:
				descString += "You know <b>who</b> scanned you";
				break;
			case HIGHEST:
				descString += "You know who scanned you";
				break;
			}

			descString += "<br/>Cost to upgrade: <ul>";
			switch (level) {
			case LOWEST:
				descString += "<li>Metal: <b>" + 0 + "</b>";
				descString += "<li>Crystal: <b>" + 0 + "</b>";
				descString += "<li>Gold: <b>" + 0 + "</b>";
				break;
			case LOW:
				descString += "<li>Metal: <b>" + Conf.COST_LEVEL_UP[level.ordinal() - 1][0] + "</b>";
				descString += "<li>Crystal: <b>" + Conf.COST_LEVEL_UP[level.ordinal() - 1][2] + "</b>";
				descString += "<li>Gold: <b>" + Conf.COST_LEVEL_UP[level.ordinal() - 1][2] + "</b>";
				break;
			case MODERATE:
				descString += "<li>Metal: <b>" + Conf.COST_LEVEL_UP[level.ordinal() - 1][0] + "</b>";
				descString += "<li>Crystal: <b>" + Conf.COST_LEVEL_UP[level.ordinal() - 1][2] + "</b>";
				descString += "<li>Gold: <b>" + Conf.COST_LEVEL_UP[level.ordinal() - 1][2] + "</b>";
				break;
			case HIGH:
				descString += "<li>Metal: <b>" + Conf.COST_LEVEL_UP[level.ordinal() - 1][0] + "</b>";
				descString += "<li>Crystal: <b>" + Conf.COST_LEVEL_UP[level.ordinal() - 1][2] + "</b>";
				descString += "<li>Gold: <b>" + Conf.COST_LEVEL_UP[level.ordinal() - 1][2] + "</b>";
				break;
			case HIGHEST:
				descString += "<li>Metal: <b>" + Conf.COST_LEVEL_UP[level.ordinal() - 1][0] + "</b>";
				descString += "<li>Crystal: <b>" + Conf.COST_LEVEL_UP[level.ordinal() - 1][2] + "</b>";
				descString += "<li>Gold: <b>" + Conf.COST_LEVEL_UP[level.ordinal() - 1][2] + "</b>";
				break;
			}
			descString += "</ul>";

			descString += "<br/>Time to upgrade: ";
			switch (level) {
			case LOWEST:
				descString += "<b>" + 0 + "</b> ticks";
				break;
			case LOW:
				descString += "<b>" + Conf.ETA_LEVEL_UP_LEVEL[level.ordinal() - 1] + "</b> ticks";
				break;
			case MODERATE:
				descString += "<b>" + Conf.ETA_LEVEL_UP_LEVEL[level.ordinal() - 1] + "</b> ticks";
				break;
			case HIGH:
				descString += "<b>" + Conf.ETA_LEVEL_UP_LEVEL[level.ordinal() - 1] + "</b> ticks";
				break;
			case HIGHEST:
				descString += "<b>" + Conf.ETA_LEVEL_UP_LEVEL[level.ordinal() - 1] + "</b> ticks";
				break;
			}

			Label l = new Label(descString, Label.CONTENT_XHTML);
			if (level.ordinal() <= currentLevel) {
				l.setEnabled(false);
			}
			l.addStyleName("techlevel-details");
			p.addComponent(l);
			((AbstractOrderedLayout) p.getContent()).setSpacing(true);

			Button b = new Button("advance", new TechAdvanceClickListener());
			l = new Label("Level up in progress");

			if (currentLevel + 1 == level.ordinal()) {
				if (activeCommands.isEmpty()) {
					p.addComponent(b);
				} else {
					p.addComponent(l);
				}
			}
			if (currentLevel + 1 < level.ordinal()) {
				p.addComponent(b);
			}

			if (level.ordinal() > currentLevel + 1) {
				b.setEnabled(false);
			}

			p.getContent().setSizeFull();
			p.getContent().setHeight(null);
		}
	}

	private class TechAdvanceClickListener implements ClickListener {

		private static final long serialVersionUID = 8507764964844288939L;

		public void buttonClick(ClickEvent event) {
			if (VaadinPA.getPlanet().canLevelUp()) {
				try {
					TechAdvanceCommand cmd = new TechAdvanceCommand(VaadinPA.getPlanet());
					CommandHandler.handle(cmd);
				} catch (NotEnoughFundsException e) {
					NotificationUtil.warn("", "Not enough resources");
				}
			} else {
				NotificationUtil.notify("Can't issue command", "Not enough resources");
			}

			reload();
		}
	}

	@Override
	public String getTitle() {
		return "Tech upgrades";
	}

	@SuppressWarnings("unchecked")
	@Override
	protected List<? extends Command> getCommands() {
		return CommandHandler.getEvents(TechAdvanceCommand.class);
	}
}
